﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Kgb.Model.Models;
using Kgb.Web2.Repository;
using Kgb.Web2.Util;

namespace Kgb.Web2.Controllers
{
    public class GameController : Controller
    {
        private Player player;

        private bool Validate()
        {
            if (Session["player"] == null) // player não foi criado
                return false;

            player = Session["player"] as Player;

            if (string.IsNullOrEmpty(player.Session())) // sessão inválida
                return false;

            return true;
        }
        
        private bool ValidateLobby(int id)
        {
            if (id != 1) // hardcode : Só existe o lobbie 1 no serviço.
                return false;

            return Validate();
        }

        private bool ValidateRoom(int id)
        {
            if (!Validate())
                return false;

            if (player.RoomId == null || player.RoomId != id)
                return false;

            ViewData["roomId"] = id;

            return true;
        }
        //
        // GET: /Game/Lobbie/1
        [AllowAnonymous]
        public ActionResult Lobby(int id)
        {
            if (!ValidateLobby(id))
                throw new HttpException(404, "HTTP/1.1 404 Not Found");

            return View();
        }

        //
        // GET: /Game/WaitingRoom/1
        [AllowAnonymous]
        public ActionResult WaitingRoom(int id)
        {
            if (!ValidateRoom(id))
                throw new HttpException(404, "HTTP/1.1 404 Not Found");

            return View();
        }

        //
        // GET: /Game/Room/1
        [AllowAnonymous]
        public ActionResult Room(int id)
        {
            if (!ValidateRoom(id))
                throw new HttpException(404, "HTTP/1.1 404 Not Found");

            return View();
        }

        //
        // Get: /Game/GetLobbyRooms/1

        [AllowAnonymous]
        public ActionResult GetLobbyRooms(int id, int page, int take)
        {
            if (!ValidateLobby(id))
                throw new HttpException(404, "HTTP/1.1 404 Not Found");
            
            LobbyRepository repository = new LobbyRepository(new JsonNetSerialization());

            try
            {
                return Json(repository.GetRooms(id, page, take), JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex.Message);

            }

            // If we got this far, something failed
            return Json(new { errors = GetErrorsFromModelState() }, JsonRequestBehavior.AllowGet);
        }

        //
        // Get: /Game/GetRoomLocations

        [AllowAnonymous]
        public ActionResult GetRoomLocations(int roomId)
        {
            if (!ValidateRoom(roomId))
                throw new HttpException(404, "HTTP/1.1 404 Not Found");

            RoomRepository repository = new RoomRepository(new JsonNetSerialization());

            try
            {
                return Json(repository.GetLocations(roomId, 0), JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex.Message);

            }

            // If we got this far, something failed
            return Json(new { errors = GetErrorsFromModelState() }, JsonRequestBehavior.AllowGet);
        }

        //
        // POST: /Game/LobbyAccessRoom/1
        [AllowAnonymous]
        [HttpPost]
        public ActionResult LobbyAccessRoom(int roomId)
        {
            if (!ModelState.IsValid)
                ModelState.AddModelError("", "Invalid Model State!");
            
            if (roomId < 1)
                ModelState.AddModelError("", "Room Id must be greater than 0!");

            if (!Validate())
                ModelState.AddModelError("", "Invalid access, player and session id must be defined!");


            if (!ModelState.Any(x=>x.Value.Errors.Count > 0))
            {
                RoomRepository repository = new RoomRepository(new JsonNetSerialization());

                Room room = repository.Get(roomId);

                if (room == null || room.LobbyId != 1)
                    ModelState.AddModelError("", "Invalid room!");

                if (room.State == "cheia")
                    ModelState.AddModelError("", "A sala está cheia e não pode ser utilizada!");

                if (room.State == "aguardando" || room.State == "jogando")
                    ModelState.AddModelError("", "A sala está em jogo e não pode ser utilizada!");


                if (!ModelState.Any(x=>x.Value.Errors.Count > 0))
                {
                    try
                    {
                        player = repository.AccessRoom(player, room);
                        return Json(new { success = true, redirect = String.Format("Game/WaitingRoom/{0}", player.RoomId)});
                    }
                    catch (Exception ex)
                    {
                        ModelState.AddModelError("", ex.Message);
                    }
                }
            }

            // If we got this far, something failed
            return Json(new { errors = GetErrorsFromModelState() });
        }

        private IEnumerable<string> GetErrorsFromModelState()
        {
            return ModelState.SelectMany(x => x.Value.Errors.Select(error => error.ErrorMessage));
        }
    }
}
